<script lang="ts" setup>
// import type { Identifier, XYCoord } from 'dnd-core';

import { computed, ref, unref } from 'vue';

import { toRefs } from '@vueuse/core';
import { useDrag, useDrop } from 'vue3-dnd';
// import { ItemTypes } from './ItemTypes';

const props = defineProps<{
  className: string;
  end?: () => void;
  id: any;
  index: number;
  islodin: boolean;
  moveCard: (dragIndex: number, hoverIndex: number) => void;
  removeCard: (index: number) => void;
}>();

interface DragItem {
  index: number;
  id: string;
  type: string;
}

const card = ref<HTMLDivElement>();
const [dropCollect, drop] = useDrop<DragItem, void>({
  accept: 'card',
  collect(monitor) {
    return {
      handlerId: monitor.getHandlerId(),
    };
  },
  hover(item: DragItem, monitor) {
    if (!card.value) {
      return;
    }
    const dragIndex = item.index;
    const hoverIndex = props.index;
    // Don't replace items with themselves
    if (dragIndex === hoverIndex) {
      return;
    }

    // Determine rectangle on screen
    const hoverBoundingRect = card.value?.getBoundingClientRect();

    // Get vertical middle
    const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;

    // Determine mouse position
    const clientOffset = monitor.getClientOffset();

    // Get pixels to the top
    const hoverClientY = (clientOffset as any).y - hoverBoundingRect.top;

    // Only perform the move when the mouse has crossed half of the items height
    // When dragging downwards, only move when the cursor is below 50%
    // When dragging upwards, only move when the cursor is above 50%

    // Dragging downwards
    if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) {
      return;
    }

    // Dragging upwards
    if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) {
      return;
    }

    // Time to actually perform the action
    props.moveCard(dragIndex, hoverIndex);

    // Note: we're mutating the monitor item here!
    // Generally it's better to avoid mutations,
    // but it's good here for the sake of performance
    // to avoid expensive index searches.
    item.index = hoverIndex;
  },
});

const [collect, drag] = useDrag({
  type: 'card',
  item: () => {
    return { id: props.id, index: props.index };
  },
  collect: (monitor: any) => ({
    isDragging: monitor.isDragging(),
  }),
  end: () => {
    // console.log('end拖放结束', item, monitor);
    props.end && props.end();
  },
});

const { handlerId } = toRefs(dropCollect) as any;
const { isDragging } = toRefs(collect);
const opacity = computed(() => (unref(isDragging) ? 0 : 1));

const setRef: any = (el: HTMLDivElement) => {
  card.value = drag(drop(el)) as HTMLDivElement;
};
</script>

<template>
  <a-spin :spinning="islodin || false">
    <div
      :ref="setRef"
      :class="className"
      :data-handler-id="handlerId"
      :style="{ opacity }"
      class="card"
    >
      <slot></slot>
    </div>
  </a-spin>
</template>

<style lang="scss" scoped>
// .card {
//   padding: 0.5rem 1rem;
//   margin-bottom: 0.5rem;
//   cursor: move;
//   background-color: white;
//   border: 1px dashed gray;
// }

// .topmo {
//   .boto {
//     bottom: -1rem;
//     background: rgb(0 0 0 / 50%);
//     transition: all 0.1s;
//   }

//   &:hover .boto {
//     bottom: 0;
//   }
// }
</style>
